package active

import (
	"fmt"
	"server/game/cache"
	"server/game/model"
	"server/share/config"

	"github.com/hwcer/cosgo/times"
	"github.com/hwcer/cosgo/values"
	"github.com/hwcer/cosmo"
	"github.com/hwcer/yyds/context"
	"github.com/hwcer/yyds/errors"
	"github.com/hwcer/yyds/options"
	"github.com/hwcer/yyds/players/player"
	"github.com/hwcer/yyds/players/verify"
)

/*
商业玩法，充值订单，月卡，商场 等赚钱的东西
*/

var db = model.DB()

func init() {
	Register(Getter)
}

func Register(i any, prefix ...string) {
	arr := []string{"active"}
	if len(prefix) > 0 {
		arr = append(arr, prefix...)
	} else {
		arr = append(arr, "%v")
	}
	context.Register(i, arr...)
}

// Getter 获取列表
func Getter(c *context.Context) interface{} {
	paging := &cosmo.Paging{}
	if err := c.Bind(paging); err != nil {
		return err
	}
	//p := c.Player()
	paging.Rows = make([]*model.Active, 0)
	tx := db.Omit("uid", "update").Order("update", -1).Page(paging, "uid = ?", c.Uid())
	if tx.Error != nil {
		return tx
	}
	now := c.Unix()
	for _, row := range paging.Rows.([]*model.Active) {
		if row.Expire > 0 && row.Expire < now {
			row.Attach = ""
		}
	}
	return paging
}

// 后台配置
type Config struct {
	Id     uint32      `json:"id" bson:"_id"`
	Code   string      `json:"code" bson:"code"`
	AType  ConfigAType `json:"AType" bson:"AType"`
	Ignore int64       `json:"ignore"`
	Attach string      `json:"attach"`
	Expire []int64     `json:"expire"`
}

func (c *Config) Init() error {
	query := make(values.Values)
	if c.Id != 0 {
		query["id"] = c.Id
	} else if c.Code != "" {
		query["code"] = c.Code
	} else {
		return fmt.Errorf("id and code can not be empty")
	}
	query.Set("GZone", options.Game.Sid)
	if err := options.Master.Post(options.MasterApiTypeConfigInfo, query, c); err != nil {
		return err
	}
	return nil
}

func (c *Config) Verify(p *player.Player) (t [2]int64, err error) {
	role := p.Document(config.ITypeRole).Any().(*model.Role)
	if c.Ignore > 0 && role.Create > c.Ignore {
		err = errors.New("ignored")
		return
	}
	return p.Times.Verify(c.Expire)
}

type VerifyConfig interface {
	GetArgs() []int32
	GetExpire() []int64
}
type VerifyResult struct {
	VerifyConfig
	Cycle  *times.Cycle
	Active *model.Active
}

// Verify 活动检查
// argsNum 配置中args至少几个参数
func Verify(p *player.Player, id int32, mod int32, argsNum int) (h *cache.Active, r *VerifyResult, err error) {
	ac := config.Data.Active[id]
	if ac == nil {
		return nil, nil, errors.ErrConfigEmpty
	}
	if len(ac.Args) < argsNum {
		return nil, nil, errors.Errorf(0, "Active config args error")
	}

	if ac.Mod != mod {
		return nil, nil, errors.Errorf(0, "active config mod mismatched")
	}
	r = &VerifyResult{VerifyConfig: ac}
	h = cache.GetActive(p.Updater)
	if r.Active, r.Cycle, err = h.Verify(id); err != nil {
		return
	}
	return
}

func Target(s verify.Target, c *times.Cycle) verify.Target {
	if s.GetCondition() != verify.ConditionHistory {
		return s
	}
	return &TargetWithTime{Target: s, Cycle: c}
}

type TargetWithTime struct {
	verify.Target
	Cycle *times.Cycle
}

func (t *TargetWithTime) GetTimes() [2]int64 {
	r := [2]int64{}
	if s, e := t.Cycle.Start(); e == nil {
		r[0] = s.Now().Unix()
	}
	if s, e := t.Cycle.Expire(); e == nil {
		r[1] = s.Now().Unix()
	}
	return r
}
